package com.amu.aidemo.android.audio

import android.media.AudioFormat
import android.media.AudioManager
import android.media.AudioTrack
import android.util.Log

private const val TAG = "AudioPlayer"

/**
 * PCM 音频播放器（简化版，参考其他项目实现）
 */
class AudioPlayer {
    companion object {
        private const val SAMPLE_RATE = 16000 // 采样率
    }

    private lateinit var audioTrack: AudioTrack
    private var trackReady = false
    
    /**
     * 初始化音频播放器
     */
    fun initialize() {
        try {
            // 如果已经初始化，先释放旧的资源
            if (trackReady) {
                Log.d(TAG, "AudioPlayer already initialized, releasing old instance...")
                release()
            }
            
            val bufferSize = AudioTrack.getMinBufferSize(
                SAMPLE_RATE,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT
            )
            
            if (bufferSize == AudioTrack.ERROR_BAD_VALUE || bufferSize == AudioTrack.ERROR) {
                Log.e(TAG, "Invalid audio parameters, bufferSize: $bufferSize")
                return
            }
            
            @Suppress("DEPRECATION")
            audioTrack = AudioTrack(
                AudioManager.STREAM_MUSIC,
                SAMPLE_RATE,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSize,
                AudioTrack.MODE_STREAM
            )
            
            // 必须检查初始化状态
            if (audioTrack.state == AudioTrack.STATE_INITIALIZED) {
                audioTrack.play() // 只有初始化成功后才能调用
                trackReady = true
                Log.d(TAG, "AudioPlayer initialized and started, buffer size: $bufferSize")
            } else {
                Log.e(TAG, "AudioTrack initialization failed, state: ${audioTrack.state}")
                trackReady = false
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to initialize AudioPlayer", e)
            trackReady = false
        }
    }

    /**
     * 写入音频数据（分块写入，处理缓冲区满的情况）
     */
    fun write(audioData: ByteArray) {
        if (!trackReady) {
            Log.w(TAG, "AudioTrack not ready")
            return
        }
        
        if (audioData.isEmpty()) {
            return
        }
        
        try {
            var offset = 0
            val chunkSize = 2048  // 每次写入 2KB
            
            while (offset < audioData.size) {
                val remaining = audioData.size - offset
                val toWrite = minOf(remaining, chunkSize)
                
                val written = audioTrack.write(audioData, offset, toWrite)
                
                if (written < 0) {
                    Log.e(TAG, "Write error: $written at offset $offset")
                    break
                } else if (written == 0) {
                    // 缓冲区满了，等待一小段时间
                    Thread.sleep(10)
                } else {
                    offset += written
                }
            }
            
            if (offset == audioData.size) {
                Log.d(TAG, "Successfully wrote ${audioData.size} bytes")
            } else {
                Log.w(TAG, "Partial write: $offset/${audioData.size} bytes")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to write audio", e)
        }
    }
    

    /**
     * 停止播放
     */
    fun stop() {
        if (!trackReady) return
        
        try {
            audioTrack.pause()
            audioTrack.flush()
            Log.d(TAG, "Audio stopped and flushed")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to stop audio", e)
        }
    }

    /**
     * 等待播放完成
     */
    fun waitForCompletion() {
        if (!trackReady) return
        
        try {
            // 等待 AudioTrack 缓冲区播放完成
            var waitCount = 0
            val maxWaitSeconds = 30 // 最多等待 30 秒
            
            while (waitCount < maxWaitSeconds * 10) {
                val playbackHeadPosition = audioTrack.playbackHeadPosition
                Thread.sleep(100)
                val newPosition = audioTrack.playbackHeadPosition
                
                // 如果播放位置不再变化，说明播放完成
                if (playbackHeadPosition == newPosition && playbackHeadPosition > 0) {
                    Thread.sleep(200) // 再等待一点确保完全播放完
                    break
                }
                
                waitCount++
            }
            
            Log.d(TAG, "Playback wait completed after ${waitCount * 100}ms")
        } catch (e: Exception) {
            Log.e(TAG, "Error waiting for completion", e)
        }
    }

    /**
     * 释放资源
     */
    fun release() {
        if (!trackReady) return
        
        try {
            if (::audioTrack.isInitialized) {
                if (audioTrack.state == AudioTrack.STATE_INITIALIZED) {
                    audioTrack.stop()
                }
                audioTrack.release()
            }
            trackReady = false
            Log.d(TAG, "AudioPlayer released")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to release AudioPlayer", e)
            trackReady = false
        }
    }
}
